x, y,
width, height);
picture = gtk_picture_new_for_paintable (piece);
- gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (picture), FALSE);
+ gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_FILL);
gtk_grid_attach (GTK_GRID (grid),
picture,
x, y,
<child>
<object class="GtkPicture" id="picture">
<property name="can-shrink">0</property>
- <property name="keep-aspect-ratio">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<property name="child">
<object class="GtkPicture">
<property name="file">resource:///org/gtk/WidgetFactory4/sunset.jpg</property>
+ <property name="content-fit">cover</property>
+ <property name="overflow">hidden</property>
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
GTK_BASELINE_POSITION_BOTTOM
} GtkBaselinePosition;
+/**
+ * GtkContentFit:
+ * @GTK_CONTENT_FIT_FILL: Make the content fill the entire allocation,
+ * without taking its aspect ratio in consideration. The resulting
+ * content will appear as stretched if its aspect ratio is different
+ * from the allocation aspect ratio.
+ * @GTK_CONTENT_FIT_CONTAIN: Scale the content to fit the allocation,
+ * while taking its aspect ratio in consideration. The resulting
+ * content will appear as letterboxed if its aspect ratio is different
+ * from the allocation aspect ratio.
+ * @GTK_CONTENT_FIT_COVER: Cover the entire allocation, while taking
+ * the content aspect ratio in consideration. This can result in an overflow
+ * if the content aspect ratio is different from the allocation aspect ratio.
+ * For this reason, you may also want to set [property@Gtk.Widget:overflow]
+ * to %GTK_OVERFLOW_HIDDEN.
+ * @GTK_CONTENT_FIT_SCALE_DOWN: The content is scaled down to fit the
+ * allocation, if needed, otherwise its original size is used.
+ *
+ * Controls how a content should be made to fit inside an allocation.
+ *
+ * Since: 4.8
+ */
+typedef enum
+{
+ GTK_CONTENT_FIT_FILL,
+ GTK_CONTENT_FIT_CONTAIN,
+ GTK_CONTENT_FIT_COVER,
+ GTK_CONTENT_FIT_SCALE_DOWN,
+} GtkContentFit;
+
/**
* GtkDeleteType:
* @GTK_DELETE_CHARS: Delete characters.
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtksnapshot.h"
+#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
#include "gdkpixbufutilsprivate.h"
PROP_ALTERNATIVE_TEXT,
PROP_KEEP_ASPECT_RATIO,
PROP_CAN_SHRINK,
+ PROP_CONTENT_FIT,
NUM_PROPERTIES
};
GFile *file;
char *alternative_text;
- guint keep_aspect_ratio : 1;
guint can_shrink : 1;
+ GtkContentFit content_fit;
};
struct _GtkPictureClass
height = gtk_widget_get_height (widget);
ratio = gdk_paintable_get_intrinsic_aspect_ratio (self->paintable);
- if (!self->keep_aspect_ratio || ratio == 0)
+ if (self->content_fit == GTK_CONTENT_FIT_FILL || ratio == 0)
{
gdk_paintable_snapshot (self->paintable, snapshot, width, height);
}
else
{
double picture_ratio = (double) width / height;
+ int paintable_width = gdk_paintable_get_intrinsic_width (self->paintable);
+ int paintable_height = gdk_paintable_get_intrinsic_height (self->paintable);
- if (ratio > picture_ratio)
+ if (self->content_fit == GTK_CONTENT_FIT_SCALE_DOWN &&
+ width >= paintable_width && height >= paintable_height)
{
- w = width;
- h = width / ratio;
+ w = paintable_width;
+ h = paintable_height;
+ }
+ else if (ratio > picture_ratio)
+ {
+ if (self->content_fit == GTK_CONTENT_FIT_COVER)
+ {
+ w = height * ratio;
+ h = height;
+ }
+ else
+ {
+ w = width;
+ h = width / ratio;
+ }
}
else
{
- w = height * ratio;
- h = height;
+ if (self->content_fit == GTK_CONTENT_FIT_COVER)
+ {
+ w = width;
+ h = width / ratio;
+ }
+ else
+ {
+ w = height * ratio;
+ h = height;
+ }
}
x = (width - ceil (w)) / 2;
break;
case PROP_KEEP_ASPECT_RATIO:
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_picture_set_keep_aspect_ratio (self, g_value_get_boolean (value));
+ G_GNUC_END_IGNORE_DEPRECATIONS
break;
case PROP_CAN_SHRINK:
gtk_picture_set_can_shrink (self, g_value_get_boolean (value));
break;
+ case PROP_CONTENT_FIT:
+ gtk_picture_set_content_fit (self, g_value_get_enum (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
break;
case PROP_KEEP_ASPECT_RATIO:
- g_value_set_boolean (value, self->keep_aspect_ratio);
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+ g_value_set_boolean (value, gtk_picture_get_keep_aspect_ratio (self));
+ G_GNUC_END_IGNORE_DEPRECATIONS
break;
case PROP_CAN_SHRINK:
g_value_set_boolean (value, self->can_shrink);
break;
+ case PROP_CONTENT_FIT:
+ g_value_set_enum (value, self->content_fit);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
*
* Whether the GtkPicture will render its contents trying to preserve the aspect
* ratio.
+ *
+ * Deprecated: 4.8: Use [property@Gtk.Picture:content-fit] instead.
*/
properties[PROP_KEEP_ASPECT_RATIO] =
g_param_spec_boolean ("keep-aspect-ratio", NULL, NULL,
TRUE,
- GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+ GTK_PARAM_READWRITE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_DEPRECATED);
/**
* GtkPicture:can-shrink: (attributes org.gtk.Property.get=gtk_picture_get_can_shrink org.gtk.Property.set=gtk_picture_set_can_shrink)
TRUE,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * GtkPicture:content-fit: (attributes org.gtk.Property.get=gtk_picture_get_content_fit org.gtk.Property.set=gtk_picture_set_content_fit)
+ *
+ * How the content should be resized to fit inside the `GtkPicture`.
+ */
+ properties[PROP_CONTENT_FIT] =
+ g_param_spec_enum ("content-fit", NULL, NULL,
+ GTK_TYPE_CONTENT_FIT,
+ GTK_CONTENT_FIT_CONTAIN,
+ GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
gtk_widget_class_set_css_name (widget_class, I_("picture"));
gtk_picture_init (GtkPicture *self)
{
self->can_shrink = TRUE;
- self->keep_aspect_ratio = TRUE;
+ self->content_fit = GTK_CONTENT_FIT_CONTAIN;
}
/**
*
* If set to %FALSE or if the contents provide no aspect ratio,
* the contents will be stretched over the picture's whole area.
+ *
+ * Deprecated: 4.8: Use [method@Gtk.Picture.set_content_fit] instead. If still
+ * used, this method will always set the [property@Gtk.Picture:content-fit]
+ * property to `GTK_CONTENT_FIT_CONTAIN` if @keep_aspect_ratio is true,
+ * otherwise it will set it to `GTK_CONTENT_FIT_FILL`.
*/
void
gtk_picture_set_keep_aspect_ratio (GtkPicture *self,
gboolean keep_aspect_ratio)
{
- g_return_if_fail (GTK_IS_PICTURE (self));
-
- if (self->keep_aspect_ratio == keep_aspect_ratio)
- return;
-
- self->keep_aspect_ratio = keep_aspect_ratio;
-
- gtk_widget_queue_draw (GTK_WIDGET (self));
-
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_KEEP_ASPECT_RATIO]);
+ if (keep_aspect_ratio)
+ gtk_picture_set_content_fit (self, GTK_CONTENT_FIT_CONTAIN);
+ else
+ gtk_picture_set_content_fit (self, GTK_CONTENT_FIT_FILL);
}
/**
* Returns whether the `GtkPicture` preserves its contents aspect ratio.
*
* Returns: %TRUE if the self tries to keep the contents' aspect ratio
+ *
+ * Deprecated: 4.8: Use [method@Gtk.Picture.get_content_fit] instead. This will
+ * now return `FALSE` only if [property@Gtk.Picture:content-fit] is
+ * `GTK_CONTENT_FIT_FILL`. Returns `TRUE` otherwise.
*/
gboolean
gtk_picture_get_keep_aspect_ratio (GtkPicture *self)
{
g_return_val_if_fail (GTK_IS_PICTURE (self), TRUE);
- return self->keep_aspect_ratio;
+ return self->content_fit != GTK_CONTENT_FIT_FILL;
}
/**
return self->can_shrink;
}
+/**
+ * gtk_picture_set_content_fit: (attributes org.gtk.Method.set_property=content-fit)
+ * @self: a `GtkPicture`
+ * @content_fit: the content fit mode
+ *
+ * Sets how the content should be resized to fit the `GtkPicture`.
+ *
+ * See [enum@Gtk.ContentFit] for details.
+ *
+ * If you use `GTK_CONTENT_FIT_COVER`, you may also want to set the
+ * [property@Gtk.Widget:overflow] to `GTK_OVERFLOW_HIDDEN`, otherwise the
+ * paintable will overflow the widget allocation if the aspect ratio of the
+ * paintable is different from the one of the `GtkPicture` allocation.
+ */
+void
+gtk_picture_set_content_fit (GtkPicture *self,
+ GtkContentFit content_fit)
+{
+ g_return_if_fail (GTK_IS_PICTURE (self));
+
+ if (self->content_fit == content_fit)
+ return;
+
+ gboolean notify_keep_aspect_ratio = (content_fit == GTK_CONTENT_FIT_FILL ||
+ self->content_fit == GTK_CONTENT_FIT_FILL);
+
+ self->content_fit = content_fit;
+
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CONTENT_FIT]);
+
+ if (notify_keep_aspect_ratio)
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_KEEP_ASPECT_RATIO]);
+}
+
+/**
+ * gtk_picture_get_content_fit: (attributes org.gtk.Method.get_property=content-fit)
+ * @self: a `GtkPicture`
+ *
+ * Returns the fit mode for the content of the `GtkPicture`.
+ *
+ * See [enum@Gtk.ContentFit] for details.
+ *
+ * Returns: the content fit mode
+ */
+GtkContentFit
+gtk_picture_get_content_fit (GtkPicture *self)
+{
+ g_return_val_if_fail (GTK_IS_PICTURE (self), FALSE);
+
+ return self->content_fit;
+}
+
/**
* gtk_picture_set_alternative_text: (attributes org.gtk.Method.set_property=alternative-text)
* @self: a `GtkPicture`
void gtk_picture_set_pixbuf (GtkPicture *self,
GdkPixbuf *pixbuf);
-GDK_AVAILABLE_IN_ALL
+GDK_DEPRECATED_IN_4_8_FOR(gtk_picture_set_fit_mode)
void gtk_picture_set_keep_aspect_ratio (GtkPicture *self,
gboolean keep_aspect_ratio);
-GDK_AVAILABLE_IN_ALL
+GDK_DEPRECATED_IN_4_8_FOR(gtk_picture_get_fit_mode)
gboolean gtk_picture_get_keep_aspect_ratio (GtkPicture *self);
GDK_AVAILABLE_IN_ALL
void gtk_picture_set_can_shrink (GtkPicture *self,
GDK_AVAILABLE_IN_ALL
gboolean gtk_picture_get_can_shrink (GtkPicture *self);
+GDK_AVAILABLE_IN_4_8
+void gtk_picture_set_content_fit (GtkPicture *self,
+ GtkContentFit content_fit);
+GDK_AVAILABLE_IN_4_8
+GtkContentFit gtk_picture_get_content_fit (GtkPicture *self);
+
GDK_AVAILABLE_IN_ALL
void gtk_picture_set_alternative_text (GtkPicture *self,
const char *alternative_text);
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-100x100.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-100x100.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-100x100.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-100x100.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-150x150.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-150x150.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-150x150.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-150x150.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-200x200.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-200x200.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-200x200.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-200x200.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-20x20.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-20x20.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-20x20.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-20x20.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-300x300.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-300x300.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child type="overlay">
<object class="GtkPicture">
<property name="paintable">green-300x300.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkPicture">
<property name="paintable">green-300x300.png</property>
- <property name="keep-aspect-ratio">0</property>
+ <property name="content-fit">fill</property>
<property name="can-shrink">1</property>
<property name="halign">center</property>
<property name="valign">center</property>